package com.swn.common.util;


import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;

/**
 * 属性拷贝：前面null的值不覆盖后面的值
 * 
 * @author taozhaocai
 * @Date 2016年6月22日  下午3:34:42
 * @Note 方法来源：http://blog.csdn.net/thc1987/article/details/7546109
 */
public abstract class BeanUtils extends org.springframework.beans.BeanUtils {  
  
  public static void copyProperties(Object source, Object target) {  
    Class<?> actualEditable = target.getClass();  
    PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);  
    for (PropertyDescriptor targetPd : targetPds) {  
      if (targetPd.getWriteMethod() != null) {  
        PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());  
        if (sourcePd != null && sourcePd.getReadMethod() != null) {  
          try {  
            Method readMethod = sourcePd.getReadMethod();  
            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {  
              readMethod.setAccessible(true);  
            }  
            Object value = readMethod.invoke(source); 
            /*Type returnType = readMethod.getGenericReturnType();
            if (returnType instanceof ParameterizedType) 如果是泛型类型 {
            	               Type[] types = ((ParameterizedType) returnType)
            	                        .getActualTypeArguments();// 泛型类型列表
            	                System.out.println("  TypeArgument: ");
            	for (Type type : types) {
            	                    System.out.println(""+ type);
            	                }
            	           }*/
            
            //如果特殊处理null问题，可在此处处理
            /*if(value ==null && Integer.class == getClass(returnType)){
            	
            	value = new Integer(0);//如果为null,则转换为0
        	}*/
            // 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等  
            if (value != null) {  
              Method writeMethod = targetPd.getWriteMethod();  
              if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {  
                writeMethod.setAccessible(true);  
              }  
              writeMethod.invoke(target, value);  
            }
          } catch (Throwable ex) {  
            throw new RuntimeException("Could not copy properties from source to target", ex);  
          }  
        }  
      }  
    }  
  }  
  
  
  /***根据Type获取返回值真正类型***/
  private static final String TYPE_NAME_PREFIX = "class ";

  public static String getClassName(Type type) {
      if (type==null) {
          return "";
      }
      String className = type.toString();
      if (className.startsWith(TYPE_NAME_PREFIX)) {
          className = className.substring(TYPE_NAME_PREFIX.length());
      }
      return className;
  }

  public static Class<?> getClass(Type type) 
              throws ClassNotFoundException {
      String className = getClassName(type);
      if (className==null || className.isEmpty()) {
          return null;
      }
      return Class.forName(className);
  }
  
}  